package com.example.travel.Service;

import com.example.travel.domain.Message;
import com.example.travel.domain.Messages;
import com.example.travel.utils.MessageUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 功能：
 * 作者：lln
 * 日期：2025/3/14 15:24
 */
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfigurator.class)
@Component
public class ChatEndpoint {
    @Autowired
    private MessageServer messageService;
    @Autowired
    private UserServer userServer;

    //用来存储每个客户端对象对应的ChatEndpoint对象
    private static Map<String, ChatEndpoint> onlineUsers = new ConcurrentHashMap<>();

    //声明一个Session对象，通过该对象可以发送消息给特定的客户端
    private Session session;

    //声明一个HttpSession对象，用来获取我们之前发送消息的用户
    private HttpSession httpSession;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        //将局部Session对象赋值给成员变量session
        this.session = session;
        //获取HttpSession对象
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());

        //从HttpSession对象中获取用户名
        String username = (String) httpSession.getAttribute("user");

        System.out.println("用户：" + username + "连接成功");
        //将用户名作为键，ChatEndpoint对象作为值，存储到onlineUsers集合中
        onlineUsers.put(username, this);

        // 查询并推送离线消息
        List<Messages> offlineMessages = messageService.getOfflineMessages(username);
        for (Messages msg : offlineMessages) {
            String resultMessage = MessageUtils.getMessage(false, msg.getFromUser(), msg.getMessageContent());
            session.getAsyncRemote().sendText(resultMessage);
            // 更新消息状态为已读
            messageService.markMessageAsRead(msg.getMessageId());
        }
        //将当前在线用户的用户名推送给所有客户端
        //1. 获取消息
        String message = MessageUtils.getMessage(true,null,getNames());
        //2. 调用方法进行系统消息的推送
        broadcastAllUers(message);
    }
    private void broadcastAllUers(String message) {
        try{
            Set<String> names = onlineUsers.keySet();
            for (String name : names) {
                ChatEndpoint chatEndpoint = onlineUsers.get(name);
                chatEndpoint.session.getAsyncRemote().sendText(message);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private Set<String> getNames() {
        return onlineUsers.keySet();
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            //将message转换为Message对象
            ObjectMapper mapper = new ObjectMapper();
            Message mess = mapper.readValue(message, Message.class);
            //获取要将消息发送给的用户
            String toName = mess.getToName();
            //获取消息内容
            String data = mess.getMessage();
            //获取当前登录的用户
            String username = (String) httpSession.getAttribute("user");
            //获取推送给指定用户的消息
            //String resultMessage = MessageUtils.getMessage(false,username,data);
            //发送数据
            //onlineUsers.get(toName).session.getAsyncRemote().sendText(resultMessage);
            // 检查是否是好友
            if (!isFriend(username, toName)) {
                throw new Exception("You are not friends with this user.");
            }

            // 存储消息到数据库
            saveMessageToDatabase(username, toName, data);

            // 如果好友在线，直接推送消息
            if (onlineUsers.containsKey(toName)) {
                String resultMessage = MessageUtils.getMessage(false, username, data);
                onlineUsers.get(toName).session.getAsyncRemote().sendText(resultMessage);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private boolean isFriend(String user1, String user2) {
        // 方法 userServer.isFriend(user1, user2) 来查询好友关系
        return userServer.isFriend(user1, user2);
    }

    private void saveMessageToDatabase(String fromUser, String toUser, String messageContent) {
        // 方法 messageService.saveMessage(fromUser, toUser, messageContent)
        messageService.saveMessage(fromUser, toUser, messageContent);
    }


    @OnClose
    public void onClose(Session session) {
        //从容器中移除指定用户
        String username = (String) httpSession.getAttribute("user");
        onlineUsers.remove(username);
        //获取推送的消息
        String message = MessageUtils.getMessage(true,null,getNames());
        broadcastAllUers(message);
    }
}
